package com.cman777.springc.encode.advice.d4t;


import com.cman777.springc.common.helper.AESUtil;
import com.cman777.springc.common.helper.RsaUtils;
import com.cman777.springc.encode.advice.ARequestAdvice;
import com.cman777.springc.encode.advice.d4t.properties.EncodeProperties;
import com.cman777.springc.encode.exception.DecryptEncryptException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.web.bind.annotation.ControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Optional;

@ControllerAdvice(basePackages = "${com.cman777.encode.basePackages}:")
@Order(Integer.MIN_VALUE)
public class RequestAdvice extends ARequestAdvice {
    private static Logger log = LoggerFactory.getLogger(RequestAdvice.class);
    @Autowired
    private EncodeProperties encodeProperties;
    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public boolean needDecryptOtherCondition() {
        return encodeProperties.isEnableDecrypt();
    }

    @Override
    public String decryptMessage2StringUTF8(HttpServletRequest request, String s) {
        String codeEncryptedStr = request.getHeader("codeEncryptedStr");
        if (StringUtils.isEmpty(codeEncryptedStr)) {
            throw new DecryptEncryptException("请求头缺少codeEncryptedStr");
        }
        String aesKey = RsaUtils.decryptByPrivateKey(encodeProperties.getPrivateKey(), codeEncryptedStr);
        AesKeyHolder.setAesKey(aesKey);
        Optional.ofNullable(aesKey).orElseThrow(() -> {
            log.warn("解密codeEncryptedStr 失败 {}", codeEncryptedStr);
            return new DecryptEncryptException("rsa解密codeEncryptedStr失败");
        });
        return aesString(s,aesKey);
    }


    private String aesString(String content,String aesKey){
        ObjectNode jsonObject= null;
        try {
            jsonObject = (ObjectNode) objectMapper.readTree(content);
        } catch (IOException e) {
            log.error("response不是个json");
            jsonObject = null;
        }
        String paramEncryptedStr = Optional.ofNullable(jsonObject).map(js -> js.get("paramEncryptedStr").asText()).orElse("");
        String decryptedParamJson = null;
        if (StringUtils.isEmpty(content)) {
            decryptedParamJson = "";
        } else {
            decryptedParamJson = AESUtil.decrypt(paramEncryptedStr, aesKey);
            Optional.ofNullable(decryptedParamJson).orElseThrow(() -> new DecryptEncryptException("请求体解密失败"));
        }
        return decryptedParamJson;
    }
}
